package com.File;

import org.junit.Test;

import java.io.*;

/**
 * 处理流之二:转换流的使用
 *
 * 1.转换流:属于字符流，看后面
 * InputStreamReader:将一个字节的输入流转换为字符的输入流
 * OutputStreamWriter:将一个字符的输出流转换为字节的输出流
 *
 * 2.作用:提供字节流和字符流之间的转换
 *
 *
 * 3.解码:字节,字节数组 ----> 字符数组，字符串
 *
 * 编码:字符数组,字符串 --->字节，字节数组
 *
 *
 * 4.字符集:补充:字符编码
 *  编码表的由来
 *     计算机只能识别二进制数据，早期由来是电信号，为了方便应用计算机，让它可以识别各个国家的文字，就将各个国家的文字用
 *     数字来表示，并一一对应，形成一张表。这就是编码表。
 *
 *  常见的编码表
 *      ASCII:美国标准信息交换码。
 *          用一个字节的7位可以表示。
 *      ISO8859-1:拉丁名表，欧洲码表
 *          用一个字节的8位表示
 *      GBK2312:中国的中文编码表，最多两个字节编码所有字符
 *      GBK:中国的中文编码表升级，融合了更多的中文文字符号，最多两个字节编码。
 *      Unicode:国际标准码，融合了目前人类使用的所有字符，为每个字符分配唯一的字符码。所有的文字都用两个字节表示。
 *      UTF-8:变长的编码方式，可以1-4个字节来表示一个字符。
 *
 *      GBK,UTF-8等编码，内部都兼容了ASCII编码，好处就是在处理英文字符时，可以节省空间。
 *
 *
 *      Unicode的缺陷:
 *      Unicode不完美，这里就有三个问题，一个是，我们已经知道，英文字母只用一个字节表示就够了，第二个问题是如何才能区别Unicode和ASCII？
 *      计算机怎么知道这两个字节表示一个字符，而不是表示两个符号呢？第三个，如果和GBK等双字节码编码方式一样，用最高位是1或0表示两个字节和一个字节。
 *      就减少了很多值无法用于表示字符，不够表示所有字符，Unicode在很长一段时间内无法推广，直到互联网的出现。
 *
 *      面向传输的众多UTF(UCS Transfer Format)标准出现了，顾名思义，UTF-8就是每次传输8个位传输数据，而UTF-16就是每次16个位。这是为传输而设计的编码。
 *      并使编码无国界，这样就可以显式全世界上所有的文化的字符了。
 *
 *      Unicode只是定义了一个庞大的，全球通用的字符集，并为每个字符规定了唯一确定的编号，具体存储成什么样的字节流，取决于字符编码方案。
 *      推荐的Unicode编码就是UTF-8和UTF-16。
 *
 *
 *      中文在UTF-8中是用3个字节存储。
 *
 *      补充:
 *      ANSI编码,通常是指平台的默认编码，例如英文操作系统中是ISO-8859-1,中文系统是GBK.
 *
 *      Unicode字符集只是定义了字符的集合和唯一编码，Unicode编码，则是对UTF-8,UCS-2/UTF=16等具体编码方案的统称而已。
 *      并不是具体的编码方案。
 *
 *
 *
 */
public class InputStreamReaderTest {


    /**
     * 此时处理异常的话，仍然应该使用try-catch-finally
     *
     * @throws IOException
     */
    @Test
    public void test1() throws IOException {
        FileInputStream fileInputStream = new FileInputStream("D:\\xuehujavaSE01\\src\\main\\java\\com\\File\\hello.txt");
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); // 使用系统默认的字符集
        //指明字符集，具体使用哪个字符集，取决于要操作的文件保存时，使用的字符集
        InputStreamReader inputStreamReader1 = new InputStreamReader(fileInputStream, "UTF-8");

        char[] chars = new char[20];

        int len;
        while ((len = inputStreamReader1.read(chars)) != -1) {
            String string = new String(chars, 0, len);
            System.out.println(string);
        }


        inputStreamReader1.close();
    }


    /**
     * 综合使用InputStreamReader和OutputStreamReader
     * 案例:读取UTF-8字符集的文件，使用转换流以GBK的形式进行存储
     */
    @Test
    public void test2() throws IOException {
        FileInputStream fileInputStream = new FileInputStream("D:\\xuehujavaSE01\\src\\main\\java\\com\\File\\hello.txt");

        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");

        FileOutputStream fileOutputStream = new FileOutputStream("D:\\xuehujavaSE01\\src\\main\\java\\com\\File\\hello_cpoy.txt");

        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "gbk");

        char[] chars = new char[20];
        int len;
        while ((len = inputStreamReader.read(chars)) != -1) {
            outputStreamWriter.write(chars, 0, len);
            System.out.println(chars);
        }

        inputStreamReader.close();
        outputStreamWriter.close();

    }

}
